/**
 * 测试运行器
 * 运行npm test并解析结果，确定所有569个测试用例是否通过
 */

const { execSync } = require('child_process');

/**
 * 运行测试并解析结果
 * @param {Object} options 配置选项
 * @returns {Object} 测试结果
 */
function runTests(options = {}) {
    const {
        timeout = 300000,        // 5分钟超时
        verbose = false,         // 详细输出
        testPattern = null,      // 特定测试模式
        coverage = false         // 是否生成覆盖率报告
    } = options;

    try {
        // 构建npm test命令
        let npmCommand = 'npm test';

        if (testPattern) {
            npmCommand += ` -- --testPathPattern="${testPattern}"`;
        }

        if (coverage) {
            npmCommand += ' -- --coverage';
        }

        if (verbose) {
            npmCommand += ' -- --verbose';
        }

        console.log(`🧪 运行测试命令: ${npmCommand}`);
        console.log('⏱️  测试执行中...');

        const startTime = Date.now();

        // 执行测试命令
        const output = execSync(npmCommand, {
            encoding: 'utf8',
            stdio: verbose ? 'inherit' : 'pipe',
            timeout: timeout
        });

        const endTime = Date.now();
        const duration = endTime - startTime;

        // 解析测试输出
        const testResults = parseTestOutput(output);

        return {
            success: true,
            exitCode: 0,
            duration: duration,
            output: output,
            ...testResults
        };

    } catch (error) {
        const endTime = Date.now();
        const duration = endTime - startTime;

        // 解析错误输出
        const testResults = parseTestOutput(error.stdout || error.message);

        return {
            success: false,
            exitCode: error.status || 1,
            duration: duration,
            output: error.stdout || error.message,
            error: error.message,
            ...testResults
        };
    }
}

/**
 * 解析测试输出，提取测试统计信息
 * @param {string} output 测试输出
 * @returns {Object} 解析结果
 */
function parseTestOutput(output) {
    const result = {
        total: 0,
        passed: 0,
        failed: 0,
        skipped: 0,
        suites: 0,
        coverage: null
    };

    if (!output) {
        return result;
    }

    // 解析测试套件统计
    const suiteMatch = output.match(/Test Suites:\s+(\d+)\s+passed,?\s*(\d+)\s+failed/);
    if (suiteMatch) {
        result.suites = {
            passed: parseInt(suiteMatch[1]) || 0,
            failed: parseInt(suiteMatch[2]) || 0
        };
    }

    // 解析测试用例统计
    const testMatch = output.match(/Tests:\s+(\d+)\s+passed,?\s*(\d+)\s+failed/);
    if (testMatch) {
        result.passed = parseInt(testMatch[1]) || 0;
        result.failed = parseInt(testMatch[2]) || 0;
        result.total = result.passed + result.failed;
    }

    // 解析跳过的测试
    const skippedMatch = output.match(/Tests:\s+\d+\s+passed,\s+\d+\s+failed,\s+(\d+)\s+skipped/);
    if (skippedMatch) {
        result.skipped = parseInt(skippedMatch[1]) || 0;
        result.total = result.passed + result.failed + result.skipped;
    }

    // 解析覆盖率信息
    const coverageMatch = output.match(/All files\s+\|\s+([\d.]+)\s+\|\s+([\d.]+)\s+\|\s+([\d.]+)\s+\|\s+([\d.]+)/);
    if (coverageMatch) {
        result.coverage = {
            statements: parseFloat(coverageMatch[1]) || 0,
            branches: parseFloat(coverageMatch[2]) || 0,
            functions: parseFloat(coverageMatch[3]) || 0,
            lines: parseFloat(coverageMatch[4]) || 0
        };
    }

    return result;
}

/**
 * 检查测试结果是否满足要求
 * @param {Object} testResult 测试结果
 * @param {Object} requirements 要求
 * @returns {boolean} 是否满足要求
 */
function checkRequirements(testResult, requirements = {}) {
    const {
        minTotalTests = 569,        // 最少测试用例数
        allowFailures = false,       // 是否允许失败
        minCoverage = null          // 最小覆盖率要求
    } = requirements;

    // 检查测试数量
    if (testResult.total < minTotalTests) {
        return false;
    }

    // 检查是否允许失败
    if (!allowFailures && testResult.failed > 0) {
        return false;
    }

    // 检查覆盖率要求
    if (minCoverage && testResult.coverage) {
        if (testResult.coverage.statements < minCoverage.statements ||
            testResult.coverage.branches < minCoverage.branches ||
            testResult.coverage.functions < minCoverage.functions ||
            testResult.coverage.lines < minCoverage.lines) {
            return false;
        }
    }

    return true;
}

/**
 * 生成测试报告
 * @param {Object} testResult 测试结果
 * @returns {string} 报告文本
 */
function generateReport(testResult) {
    const report = [];

    report.push('🧪 测试执行报告');
    report.push('='.repeat(30));
    report.push(`状态: ${testResult.success ? '✅ 通过' : '❌ 失败'}`);
    report.push(`执行时间: ${(testResult.duration / 1000).toFixed(2)}秒`);
    report.push(`退出码: ${testResult.exitCode}`);
    report.push('');

    if (testResult.total > 0) {
        report.push('📊 测试统计:');
        report.push(`总计: ${testResult.total} 个测试`);
        report.push(`通过: ${testResult.passed} 个 ✅`);
        report.push(`失败: ${testResult.failed} 个 ${testResult.failed > 0 ? '❌' : '✅'}`);
        if (testResult.skipped > 0) {
            report.push(`跳过: ${testResult.skipped} 个 ⏭️`);
        }
        report.push('');

        // 计算通过率
        const passRate = ((testResult.passed / testResult.total) * 100).toFixed(2);
        report.push(`通过率: ${passRate}%`);
        report.push('');
    }

    if (testResult.suites && (testResult.suites.passed > 0 || testResult.suites.failed > 0)) {
        report.push('📦 测试套件:');
        report.push(`通过: ${testResult.suites.passed} 个`);
        report.push(`失败: ${testResult.suites.failed} 个`);
        report.push('');
    }

    if (testResult.coverage) {
        report.push('📈 覆盖率报告:');
        report.push(`语句: ${testResult.coverage.statements}%`);
        report.push(`分支: ${testResult.coverage.branches}%`);
        report.push(`函数: ${testResult.coverage.functions}%`);
        report.push(`行数: ${testResult.coverage.lines}%`);
        report.push('');
    }

    if (!testResult.success && testResult.error) {
        report.push('❌ 错误信息:');
        report.push(testResult.error);
        report.push('');
    }

    // 检查是否满足项目要求
    const meetsRequirements = checkRequirements(testResult);
    report.push(`项目要求: ${meetsRequirements ? '✅ 满足' : '❌ 不满足'}`);

    return report.join('\n');
}

// 如果直接运行此脚本，执行测试并显示报告
if (require.main === module) {
    console.log('🚀 开始运行测试套件...\n');

    const testResult = runTests({ verbose: true });
    const report = generateReport(testResult);

    console.log(report);

    // 设置退出码
    process.exit(testResult.success ? 0 : 1);
}

module.exports = {
    runTests,
    parseTestOutput,
    checkRequirements,
    generateReport
};